package com.samsungmobile.common_module;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.Security;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringUtils;
import org.xml.sax.SAXException;

import com.samsungmobile.common.Conf;
import com.samsungmobile.common.ConfOta;
import com.samsungmobile.common.Logger;
import com.samsungmobile.common.channel.ServletManager;
import com.samsungmobile.common.db.value.StringValue;
import com.samsungmobile.common.util.EasyString;
import com.samsungmobile.common_module.Bean.SendMTMResult;
import com.samsungmobile.common_module.Exception.CommonModuleException;
import com.samsungmobile.common_module.Parser.SendMTMResultParser;
import com.samsungmobile.security.UKDESEncryptDecrypt;

public class ReceiveIpxMo extends ServletManager {
	
	// Parameter Values
	private String spDestinationAddress = "";
	private String spOriginatorAddress = "";
	private String spMessage = "";
	private String spMessageId = "";
	private String spTimeStamp = "";
	private String spOperator = "";
	private String sCountryCode = "";
	
	private final String mykey = "hjk&#20PBd!2342rtfdasdmd";
	
	private final String[] safSUCCESS = {"0","SUCCESS"};
	private final String[] safINVALID_DESTINATION_ADDRESS = {"401","INVALID_DESTINATION_ADDRESS"};
	private final String[] safINVALID_ORIGINATOR_ADDRESS = {"402","INVALID_ORIGINATOR_ADDRESS"};
	private final String[] safINVALID_MESSAGE_LENGTH = {"403","INVALID_MESSAGE_LENGTH"};
	private final String[] safINVALID_MESSAGE_ID_LENGTH = {"404","INVALID_MESSAGE_ID_LENGTH"};
	private final String[] safINVALID_TIMESTAMP_LENGTH = {"405","INVALID_TIMESTAMP_LENGTH"};
	private final String[] safINVALID_TIMESTAMP = {"406","INVALID_TIMESTAMP"};
	private final String[] safINVALID_OPERATOR = {"407","INVALID_OPERATOR"};
	private final String[] safAPI_INTERNAL_ERROR = {"500", "API_INTERNAL_ERROR"};
//	Technical problems with service provider:
	private final String sfSERVICE_ERROR = "400";
	
	/* (non-Javadoc)
	 * @see com.samsungmobile.common.channel.ServletManager#process()
	 */
	protected void process() throws Exception {

		HashMap<String,String> hm = new HashMap<String,String>();
		PrintWriter out = res.getWriter();

		try {
			res.setContentType("text/xml; charset=UTF-8");
			
			setParams(req);
			checkValidation();
			
			Vector<Properties> vRtn = getOrderContent();
			
			if ( vRtn != null && vRtn.size() != 0 ) {
				
				String sLogNo = "";
				
				if( sCountryCode.equals("gbr") || sCountryCode.equals("ger") ){
					sLogNo = singleValueQuery("SELECT SEQ_G2_DOWN_LOG_"+sCountryCode+".NEXTVAL AS VALUE FROM DUAL");
					
				}else{
					sLogNo = singleValueQuery("SELECT SEQ_G2_WEB_TRANS_"+sCountryCode+".NEXTVAL AS VALUE FROM DUAL");
					
				}
				
				SendMTMResult result = sendWapPush(sLogNo, getRs( vRtn.elementAt(0), "DDOCTITLE"));
				
		    	if ( result.getResponseCode() != 0 ) {  //if not success write MO fail log
		    		
		    		StringBuffer sbQuery = new StringBuffer();
		    		Vector vParam = new Vector();
		    		
		    		updateMoReceived(sbQuery, vParam, result, getRs( vRtn.elementAt(0), "seq"), sLogNo);
		    		if(!updateQuery(sbQuery.toString(), vParam))
		    			throw new CommonModuleException(safAPI_INTERNAL_ERROR);
		    		
		    		throw new CommonModuleException(new String[] {sfSERVICE_ERROR, result.getResponseMessage()});
		    	}

				writeLog(result, vRtn, sLogNo);
				
			}else{
				insertMoMissed();
			}
			
			hm.put("RESULT_ACK", "true");
			hm.put("RESULT_ACK_CODE", safSUCCESS[0]);
			hm.put("RESULT_ACK_MESSAGE", safSUCCESS[1]);
			
		} catch (CommonModuleException e) {
			
			hm.put("RESULT_ACK", "false");
			hm.put("RESULT_ACK_CODE", e.getMessages()[0]);
			hm.put("RESULT_ACK_MESSAGE", e.getMessages()[1]);
		
		} catch (Exception e) {
			hm.put("RESULT_ACK", "false");
			hm.put("RESULT_ACK_CODE", safAPI_INTERNAL_ERROR [0]);
			hm.put("RESULT_ACK_MESSAGE", safAPI_INTERNAL_ERROR [1]);
			e.printStackTrace();
		
		} finally {
			responseReturnXml(out, hm);
			
		}
		
	}	
	
	/**
	 * @param result
	 * @param vContent
	 * @param sLogNo
	 * @throws Exception
	 * Insert/Update table is vary up to country.
	 */
	private void writeLog(SendMTMResult result, Vector<Properties> vContent, String sLogNo) throws Exception{
		
		StringBuffer sbQuerys[];
		Vector<Object> vParams[];
		
		if( sCountryCode.equals("gbr")){
			
			sbQuerys = new StringBuffer[2] ;
			
			sbQuerys[0] = new StringBuffer();
			sbQuerys[1] = new StringBuffer();
			
			vParams = new Vector[2] ;
			
			vParams[0] = new Vector<Object>();
			vParams[1] = new Vector<Object>();

			//G_IPX_MO
			updateMoReceived(sbQuerys[0], vParams[0], result, getRs( vContent.elementAt(0), "seq"), sLogNo);
			//G2_DOWN_LOG_XXX
			insertDownLog(sbQuerys[1], vParams[1], vContent, sLogNo);
			
		}else if( sCountryCode.equals("ger")){
		
			sbQuerys = new StringBuffer[4] ;
			
			sbQuerys[0] = new StringBuffer();
			sbQuerys[1] = new StringBuffer();
			sbQuerys[2] = new StringBuffer();
			sbQuerys[3] = new StringBuffer();
			
			vParams = new Vector[4] ;
			
			vParams[0] = new Vector<Object>();
			vParams[1] = new Vector<Object>();
			vParams[2] = new Vector<Object>();
			vParams[3] = new Vector<Object>();
		
			//G_IPX_MO
			updateMoReceived(sbQuerys[0], vParams[0], result, getRs( vContent.elementAt(0), "seq"), sLogNo);
			//G2_DOWN_LOG_XXX
			insertDownLog(sbQuerys[1], vParams[1], vContent, sLogNo);
			//G2_WEB_TRANS_XXX
			insertTransLog_ger(sbQuerys[2], vParams[2], vContent, sLogNo);
			//G2_IPX_TRANS_GER
			insertIPXTransLog(sbQuerys[3], vParams[3], vContent, sLogNo);
			
		}else{
			//Spain, Italy case
			sbQuerys = new StringBuffer[2] ;
			
			sbQuerys[0] = new StringBuffer();
			sbQuerys[1] = new StringBuffer();
			
			vParams = new Vector[2] ;
			
			vParams[0] = new Vector<Object>();
			vParams[1] = new Vector<Object>();
		
			//G_IPX_MO
			updateMoReceived(sbQuerys[0], vParams[0], result, getRs( vContent.elementAt(0), "seq"), sLogNo);
			//G2_WEB_TRANS_XXX
			insertTransLog(sbQuerys[1], vParams[1], vContent, sLogNo);
		}
		
		if(!updateQuery(sbQuerys, vParams))
			throw new CommonModuleException(safAPI_INTERNAL_ERROR);
	}
	
	private void insertIPXTransLog(StringBuffer sbQuery, Vector<Object> vParam, Vector<Properties> vContent, String sLogNo ){
		
		sbQuery.append("INSERT INTO G2_IPX_TRANS_").append(sCountryCode).append("( TRAID 		\n");
		sbQuery.append("                          , SESSION_ID                              \n");
		sbQuery.append("                          , MSISDN                                  \n");
		sbQuery.append("                          , TARIFF_CLASS                            \n");
		sbQuery.append("                          , REFERENCE_ID                            \n");
		sbQuery.append("                          , CONTENT_ID                              \n");
		sbQuery.append("                          , CONTENT_NM                              \n");
//		sbQuery.append("                          , OP_CD                                   \n");
		sbQuery.append("                          , BILLING_STATUS                          \n");
		sbQuery.append("                          , DOWNLOAD_STATUS                         \n");
		sbQuery.append("                          , CREATED_YMDHMS                          \n");
		sbQuery.append("                          , LOG_NO)                                 \n");
		sbQuery.append("                    VALUES( seq_g2_ipx_trans_").append(sCountryCode).append(".NEXTVAL \n");
		sbQuery.append("                          , :SMESSAGEID                             \n");
		vParam.add(new StringValue(spMessageId));
		sbQuery.append("                          , :MSISDN                                 \n");
		vParam.add(new StringValue(spOriginatorAddress));
		sbQuery.append("                          , :SPRICE                                 \n");
		String sPrice = "EUR" + Integer.parseInt( StringUtils.replaceChars( getRs( vContent.elementAt(0), "PRICE") , ",.", "") );
		vParam.add(new StringValue(sPrice) );
		sbQuery.append("                          , :SMESSAGEID                             \n");
		vParam.add(new StringValue(spMessageId));
		sbQuery.append("                          , :CONTENT_ID                             \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "CONTENTID")));
		sbQuery.append("                          , :DDOCTITLE                              \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "DDOCTITLE")));
//		sbQuery.append("                          , :SOP_CODE                               \n");
		sbQuery.append("                          , '2'                                     \n");
		sbQuery.append("                          , '2'                                     \n");
		sbQuery.append("                          , TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')    \n");
		sbQuery.append("                          , :LOGNO )                                \n");
		vParam.add(new StringValue(sLogNo));
	}
	
	private void insertTransLog_ger(StringBuffer sbQuery, Vector<Object> vParam, Vector<Properties> vContent, String sLogNo ){
		
		sbQuery.append("INSERT INTO G2_WEB_TRANS_").append(sCountryCode).append("( TRAID  								\n");
		sbQuery.append("                        , SESSION_ID                                \n");
		sbQuery.append("                        , MSISDN                                    \n");
		sbQuery.append("                        , TARIFF_CLASS                              \n");
		sbQuery.append("                        , REFERENCE_ID                              \n");
		sbQuery.append("                        , CONTENT_ID                                \n");
		sbQuery.append("                        , CONTENT_NM                                \n");
//		sbQuery.append("                        , OP_CD                                     \n");
		sbQuery.append("                        , BILLING_STATUS                            \n");
		sbQuery.append("                        , DOWNLOAD_STATUS                           \n");
		sbQuery.append("                        , CREATED_YMDHMS                            \n");
		sbQuery.append("                        , LOG_NO)                                   \n");
		sbQuery.append("                  VALUES( SEQ_G2_WEB_TRANS_").append(sCountryCode).append( ".NEXTVAL              \n");
		sbQuery.append("                        , :SMESSAGEID                               \n");
		vParam.add(new StringValue(spMessageId));
		sbQuery.append("                        , :MSISDN                                   \n");
		vParam.add(new StringValue(spOriginatorAddress));
		sbQuery.append("                        , :SPRICE                                   \n");
		String sPrice = "EUR" + Integer.parseInt( StringUtils.replaceChars( getRs( vContent.elementAt(0), "PRICE") , ",.", "") );
		vParam.add(new StringValue(sPrice) );
		sbQuery.append("                        , :SMESSAGEID                               \n");
		vParam.add(new StringValue(spMessageId));
		sbQuery.append("                        , :CONTENT_ID                               \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "CONTENTID")));
		sbQuery.append("                        , :DDOCTITLE                                \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "DDOCTITLE")));
//		sbQuery.append("                        , :SOP_CODE                                 \n");
		sbQuery.append("                        , '2'                                       \n");
		sbQuery.append("                        , '2'                                       \n");
		sbQuery.append("                        , TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')      \n");
		sbQuery.append("                        , :LOGNO )                                  \n");
		vParam.add(new StringValue(sLogNo));
	}
	
	private void insertTransLog(StringBuffer sbQuery, Vector<Object> vParam, Vector<Properties> vContent, String sLogNo ){
		
		sbQuery.append("INSERT INTO G2_WEB_TRANS_").append(sCountryCode).append("( TRAID\n");
		sbQuery.append("                        , SESSION_ID                            \n");
		sbQuery.append("                        , MSISDN                                \n");
		sbQuery.append("                        , TARIFF_CLASS                          \n");
		sbQuery.append("                        , REFERENCE_ID                          \n");
		sbQuery.append("                        , CONTENT_ID                            \n");
		sbQuery.append("                        , CONTENT_NM                            \n");
		sbQuery.append("                        , OP_CD                                 \n");
		sbQuery.append("                        , BILLING_STATUS                        \n");
		sbQuery.append("                        , DOWNLOAD_STATUS                       \n");
		sbQuery.append("                        , CREATED_YMDHMS                        \n");
		sbQuery.append("                        , CODE                                  \n");
		sbQuery.append("                        , CTYPE_CD )                            \n");
		sbQuery.append("                  VALUES( :TRAID                                \n");
		vParam.add(new StringValue(sLogNo));
		sbQuery.append("                        , :SMESSAGEID                           \n");
		vParam.add(new StringValue(spMessageId));
		sbQuery.append("                        , :MSISDN                               \n");
		vParam.add(new StringValue(spOriginatorAddress));
		sbQuery.append("                        , :SPRICE                               \n");
		String sPrice = "EUR" + Integer.parseInt( StringUtils.replaceChars( getRs( vContent.elementAt(0), "PRICE") , ",.", "") );
		vParam.add(new StringValue(sPrice) );
		sbQuery.append("                        , :SMESSAGEID                           \n");
		vParam.add(new StringValue(spMessageId));
		sbQuery.append("                        , :CONTENT_ID                           \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "CONTENTID")));
		sbQuery.append("                        , :DDOCTITLE                            \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "DDOCTITLE")));
		sbQuery.append("                        , ''		                            \n");
		sbQuery.append("                        , '2'                                   \n");
		sbQuery.append("                        , '2'                                   \n");
		sbQuery.append("                        , TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')  \n");
		sbQuery.append("                        , :CODE                                 \n");
		
		String sCType_CD = getRs( vContent.elementAt(0), "XCTYPECD");
		String sCode = "";
		if ( sCType_CD.equals("001") && getRs( vContent.elementAt(0), "POLYCD").equals("005")){
			sCode = "999";
		}else if (sCType_CD.equals("001")){
			sCode = "005";
		}
		vParam.add(new StringValue( sCode ));
		sbQuery.append("                        , :CTYPE_CD )                           \n");
		vParam.add(new StringValue(sCType_CD));
	
	}
	
	
	/**
	 * @param sbQuery
	 * @param vParam
	 * @param result
	 * @param sSeq
	 * @param sLogNo
	 * @throws Exception
	 */
	private void updateMoReceived(StringBuffer sbQuery, Vector<Object> vParam, SendMTMResult result, String sSeq, String sLogNo) throws Exception{
		
		sbQuery.append("UPDATE G_IPX_MO									\n");
		sbQuery.append("SET DESTINATIONADDRESS 	= :DestinationAddress  \n");
		vParam.add(new StringValue(spDestinationAddress));		
		sbQuery.append("	, ORIGINATORADDRESS = :OriginatorAddress    \n");
		vParam.add(new StringValue(spOriginatorAddress));		
		sbQuery.append("	, MESSAGE 			= :Message              \n");
		vParam.add(new StringValue(spMessage));		
		sbQuery.append("	, MO_MESSAGEID		= :MessageId            \n");
		vParam.add(new StringValue(spMessageId));		
		sbQuery.append("	, TIMESTAMP 		= :TimeStamp            \n");
		vParam.add(new StringValue(spTimeStamp));		
		sbQuery.append("	, OPERATOR 			= :Operator             \n");
		vParam.add(new StringValue(spOperator));		
		sbQuery.append("	, SEND             	= :sGubn                \n");
		vParam.add(new StringValue( result.getResponseCode() == 0 ? "S" : "F" ));		
		sbQuery.append("	, MODIFIED         	= SYSDATE               \n");
		sbQuery.append("	, MESSAGEID        	= :messageid            \n");
		vParam.add(new StringValue(result.getMessageId()));		
		sbQuery.append("	, RESPONSECODE     	= :responsecode         \n");
		vParam.add(new StringValue( String.valueOf(result.getResponseCode()) ));		
		sbQuery.append("	, RESPONSEMESSAGE  	= :responseMsg          \n");
		vParam.add(new StringValue(result.getResponseMessage()));			
		sbQuery.append("	, LOG_NO           	= :log_no               \n");
		vParam.add(new StringValue(sLogNo));			
		sbQuery.append("WHERE SEQ = :seq                              \n");
		vParam.add(new StringValue(sSeq));		
		
	}
	
	/**
	 * @param sbQuery
	 * @param vParam
	 * @param vContent
	 * @param sLogNo
	 */
	private void insertDownLog(StringBuffer sbQuery, Vector<Object> vParam, Vector<Properties> vContent, String sLogNo ){
		
		sbQuery.append("INSERT INTO G2_DOWN_LOG_").append(sCountryCode).append( "( LOG_NO                               \n");
		sbQuery.append("                         , CREATED_YMDHMS                         \n");
		sbQuery.append("                         , USER_NO                                \n");
		sbQuery.append("                         , MSISDN                                 \n");
		sbQuery.append("                         , CONTENT_ID                             \n");
		sbQuery.append("                         , CP_ID                                  \n");
		sbQuery.append("                         , PRICE                                  \n");
		sbQuery.append("                         , SERVICE_TYPE                           \n");
		sbQuery.append("                         , CATEGORY_ID                            \n");
		sbQuery.append("                         , BILLING_STATUS                         \n");
		sbQuery.append("                         , DOWN_STATUS                            \n");
		sbQuery.append("                         , CTYPE_CD                               \n");
		sbQuery.append("                         , CODE                                   \n");
		sbQuery.append("                         , STATISTICS_TYPE)                       \n");
		sbQuery.append("                   VALUES( :LOG_NO                                \n");
		vParam.add(new StringValue(sLogNo)); 
		sbQuery.append("                         , TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')   \n");
		sbQuery.append("                         , :USER_NO                               \n");     
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "USERNO"))); 
		sbQuery.append("                         , :MSISDN                                \n");    
		vParam.add(new StringValue(spOriginatorAddress));
		sbQuery.append("                         , :CONTENT_ID                            \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "CONTENTID")));
		sbQuery.append("                         , :CP_ID                                 \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "XCPID")));
		sbQuery.append("                         , :PRICE                                 \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "PRICE")));
		sbQuery.append("                         , '002'                                  \n");
		sbQuery.append("                         , :CATEGORY_ID                           \n");
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "CATECD")));
		sbQuery.append("                         , '002'                                  \n");
		sbQuery.append("                         , '002'                                  \n");
		sbQuery.append("                         , :CTYPE_CD                              \n");     
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "XCTYPECD")));
		sbQuery.append("                         , :CODE                                  \n");  
		vParam.add(new StringValue(getRs( vContent.elementAt(0), "POLYCD")));
		sbQuery.append("                         , '001')                                 \n");		
	}
	
	/**
	 * @throws Exception
	 */
	private void insertMoMissed() throws Exception{
		
		StringBuffer sbQuery = new StringBuffer();
		Vector<Object> vParam = new Vector<Object>();
		
		sbQuery.append("INSERT INTO G_IPX_MO_MISSED\n");
		sbQuery.append("( SEQ, DESTINATIONADDRESS, ORIGINATORADDRESS, MESSAGE, MESSAGEID, TIMESTAMP, OPERATOR)\n");
		sbQuery.append("VALUES( G_IPX_MO_MISSED_SEQ.NEXTVAL , :DestinationAddress, :OriginatorAddress, :Message, :MessageId, :TimeStamp, :Operator)\n");
		
		vParam.add(new StringValue(spDestinationAddress));		
		vParam.add(new StringValue(spOriginatorAddress));		
		vParam.add(new StringValue(spMessage));		
		vParam.add(new StringValue(spMessageId));		
		vParam.add(new StringValue(spTimeStamp));		
		vParam.add(new StringValue(spOperator));
		
		if(!updateQuery(sbQuery.toString(), vParam))
			throw new CommonModuleException(safAPI_INTERNAL_ERROR);
	}
	
	/**
	 * @return
	 */
	private Vector<Properties> getOrderContent(){
		
		StringBuffer sbQuery = new StringBuffer();
		Vector<Object> vParam = new Vector<Object>();
		
		sbQuery.append("SELECT  SEQ, CONTENT_ID as CONTENTID, CATE_CD AS CATECD, POLY_CD AS POLYCD					\n");
		sbQuery.append("      , USER_NO AS USERNO, DDOCTITLE, XCTYPE_CD AS XCTYPECD, PRICE, XCP_ID AS XCPID \n");
	    sbQuery.append("  FROM (SELECT    A.SEQ                                                             \n");
	    sbQuery.append("             ,    A.CONTENT_ID                                                      \n");
	    sbQuery.append("             ,    A.CATE_CD                                                         \n");
	    sbQuery.append("             ,    A.POLY_CD                                                         \n");
	    sbQuery.append("             ,    A.USER_NO                                                         \n");
	    sbQuery.append("             ,    B.DDOCTITLE                                                       \n");
	    sbQuery.append("             ,    C.XCTYPE_CD                                                       \n");
	    sbQuery.append("             ,    DECODE(A.POLY_CD, NULL, C.XPRICE                                  \n");
	    sbQuery.append("                                        ,(SELECT Z.PRICE                            \n");
	    sbQuery.append("                                            FROM G2_CONTENT_SOUND Z                 \n");
	    sbQuery.append("                                           WHERE Z.CONTENT_ID = A.CONTENT_ID        \n");
	    sbQuery.append("                                             AND Z.POLY_CD    = A.POLY_CD)) PRICE   \n");
	    sbQuery.append("             ,    C.XCP_ID                                                          \n");
	    sbQuery.append("          FROM    G_IPX_MO      A                                                   \n");
	    sbQuery.append("             ,    REVISIONS               B                                         \n");
	    sbQuery.append("             ,    DOCMETA                 C                                         \n");
	    sbQuery.append("         WHERE    A.CONTENT_ID =   B.DDOCNAME                                       \n");
	    sbQuery.append("           AND    B.DID        =   C.DID                                            \n");
	    sbQuery.append("           AND    A.MSISDN     =   :OriginatorAddress                              \n");
	    vParam.add(new StringValue(spOriginatorAddress));
	    sbQuery.append("           AND    A.CREATED    >= (SYSDATE - 1)                                     \n");
	    sbQuery.append("           AND    A.SEND       =   'E'                                              \n");
	    sbQuery.append("         ORDER BY SEQ DESC)                                                         \n");
	    sbQuery.append("WHERE  ROWNUM = 1                                                                   \n");
	    
	    Vector<Properties> vRtn = selectQuery(sbQuery.toString(), vParam);
	    
	    return vRtn;
	}
	
	/**
	 * @param sLogNo
	 * @param sMessage
	 * @return
	 * @throws Exception
	 */
	private SendMTMResult sendWapPush(String sLogNo, String sMessage) throws Exception{

        SendMTMResult result = null;

    	// generate the security key for API authorization ("yyyyMM" + dest_address)
    	UKDESEncryptDecrypt ukdes = new UKDESEncryptDecrypt();
    	SimpleDateFormat sdfmt = new SimpleDateFormat(); 
    	sdfmt.applyPattern( "yyyyMM" );  
    	String sec_key = ukdes.encrypt(sdfmt.format(new Date())  + spOriginatorAddress);

    	// set the request parameters for the SendMTM API call
    	HashMap<String,String> reqList = new HashMap<String, String>();
    	reqList.put("dest_address", spOriginatorAddress);
    	reqList.put("message_type", "wappush");
    	reqList.put("message", StringUtils.defaultIfEmpty(sMessage, "Samsung") );
    	reqList.put("url", ConfOta.getConf(getCountry() + ".web2wap") + this.EncryptParam3DES(sLogNo, mykey));
    	reqList.put("source_address", spDestinationAddress);
    	reqList.put("operator", spOperator);
    	
    	if(sCountryCode.equals("esp"))
    		reqList.put("reference_id", spMessageId);
    	
    	reqList.put("sec_key", sec_key);
        
    	// use SendMTMService
    	return sendMTM(reqList);
	}
	

	/**
	 * Sends a request to the SendMTM API, receive and parses the response and returns the result
	 * @return SendMTMResult
	 */
	public SendMTMResult sendMTM(Map<String,String> paramList) throws IOException {
		
		SendMTMResult result= null;
	    String urlParams = this.setupRequestParams(paramList);

	    try {
	    	//Send request and get the response
	    	result = this.sendRequest(urlParams);
	    } 
	    catch(Exception ex) {
//	    	Logger.LOG_OTA.error("SendMTMServiceImpl:"+ex.getMessage()+"  (Stacktrace: "+ex.getStackTrace()+")");
	    	//System.out.println("SendMTMServiceImpl:"+ex.getMessage()+"  (Stacktrace: "+ex.getStackTrace()+")");
	    }
	    
	    return result;
	}
	
	/**
	 * Opens the HttpURLConnection and receives and parses the response
	 * @param urlParams
	 * @return
	 * @throws IOException
	 */
	private SendMTMResult sendRequest(String urlParams) throws IOException {
		HttpURLConnection connection = null; 
		SendMTMResult result = null;
		
		URL url = new URL((String)Conf.getConf("url_root") + "servlet_channel?class=common_module.SendMTM");
		
	    try {
		    connection = (HttpURLConnection)url.openConnection();
            connection.setConnectTimeout(2000);
            connection.setReadTimeout(20000);

		    connection.setRequestMethod("POST");
		    connection.setRequestProperty("Content-Type", 
		           "application/x-www-form-urlencoded");
			
		    connection.setRequestProperty("Content-Length", "" + 
		               Integer.toString(urlParams.getBytes().length));
		    connection.setRequestProperty("Content-Language", "de-DE");
		    
		    connection.setUseCaches (false);
		    connection.setDoInput(true);
		    connection.setDoOutput(true);
		    
		    DataOutputStream wr = new DataOutputStream (connection.getOutputStream ());
		    wr.writeBytes (urlParams);
		    wr.flush ();
		    wr.close ();

//		    Logger.LOG_OTA.debug("SendMTMServiceImpl: response code: "+connection.getResponseCode() + " || request params: "+urlParams);
//		    System.out.println("SendMTMServiceImpl: response code: "+connection.getResponseCode() + " || request params: "+urlParams);
		    
		    result = this.processResponse(connection.getInputStream());
		    
		    if(result != null) {
//		    	Logger.LOG_OTA.info("SendMTMServiceImpl: result "+result.toString());
//		    	System.out.println("SendMTMServiceImpl: result "+result.toString());
		    }
	    }
	    catch(Exception ex) {
	    	if(connection != null) {
	    		connection.disconnect();
	    	}	    	
//	    	Logger.LOG_OTA.error("SendMTMServiceImpl: "+ex.getMessage()+"  (Stacktrace: "+ex.getStackTrace()+")");
//	    	System.out.println("SendMTMServiceImpl: "+ex.getMessage()+"  (Stacktrace: "+ex.getStackTrace()+")");
	    }
	    finally {
	    	if(connection != null) {
	    		connection.disconnect();
	    	}
	    }
	
      return result;
	}
	/**
	 * Processes the response content and return the SendMTM result
	 * @param responseContent
	 * @return SendMTMResult
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 */
	private SendMTMResult processResponse(InputStream responseContent) throws ParserConfigurationException, SAXException {
		SendMTMResult result = null;

		// Parse the response with SAX
		if(responseContent != null) {
			SendMTMResultParser parser = new SendMTMResultParser();
			parser.setResponseContent(responseContent);
			parser.process();
			result = parser.getSendMTMResult();
		}
		
		return result;
	}	
	/**
	 * Setups the request parameters including URL encoding
	 * @param paramList
	 * @return String
	 * @throws UnsupportedEncodingException
	 */
	private String setupRequestParams(Map<String,String> paramList) throws UnsupportedEncodingException {
		String urlParams = "";

		for( String key: paramList.keySet() ){
			if(paramList.get( key ) != null) {
				if(urlParams != "") {
					urlParams += "&";
				}

				urlParams += key.toString()+ "="+ URLEncoder.encode(paramList.get( key ), "UTF-8");
			}
		}
		//Logger.LOG_OTA.info("SendMTMServiceImpl: request params: "+urlParams);
		System.out.println("SendMTMServiceImpl: request params: "+urlParams);
		return urlParams;
	}
 
	private void setParams(HttpServletRequest request) throws CommonModuleException{
		
		spDestinationAddress 		= EasyString.toString(request.getParameter("DestinationAddress")).trim();
		spOriginatorAddress 		= EasyString.toString(request.getParameter("OriginatorAddress")).trim();
		spMessage 					= EasyString.toString(request.getParameter("Message")).trim();
		spMessageId 				= EasyString.toString(request.getParameter("MessageId")).trim();
		spTimeStamp					= EasyString.toString(request.getParameter("TimeStamp")).trim();
		spOperator 					= EasyString.toString(request.getParameter("Operator")).trim();

		sCountryCode = ConfOta.getConf(getCountry() + ".code"); 
	}	
	
	private String getCountry() throws CommonModuleException{

		String[] saCountry = ConfOta.getArray("countries");
		String sCountry = "";
		
		for ( int i=0; i < saCountry.length; i++){
			
			if( spOriginatorAddress.startsWith(saCountry[i]) ){
				sCountry = saCountry[i];
				break;
			}
		}
		
		return sCountry;
	}	
	/**
	 * @param out
	 * @param hmResult
	 */
	private void responseReturnXml ( PrintWriter out, HashMap<String,String> hmResult ){

		String sRes = "<DeliveryResponse ack=\"" 
						+ hmResult.get("RESULT_ACK") 
						+ "\" ackCode=\""
						+ hmResult.get("RESULT_ACK_CODE")
						+"\" ackMessage=\""
						+ hmResult.get("RESULT_ACK_MESSAGE")
						+"\" />";
		out.println(sRes);
	}
	
	/**
	 * @throws Exception
	 */
	private void checkValidation() throws Exception {

		String[] saCountry = ConfOta.getArray("countries");
		String sCountries = StringUtils.join(saCountry,"|");
		
		if (!spDestinationAddress.matches("^\\d{4,11}$")) {
			throw new CommonModuleException(safINVALID_DESTINATION_ADDRESS);
		
		} else if (!spOriginatorAddress.matches("^("+sCountries+")\\d{9,11}")) {
			throw new CommonModuleException(safINVALID_ORIGINATOR_ADDRESS);
			
		} else if( spMessage.length() > 280 ){
			throw new CommonModuleException(safINVALID_MESSAGE_LENGTH);
			
		} else if( spMessageId.length() > 22 ){
			throw new CommonModuleException(safINVALID_MESSAGE_ID_LENGTH);
		
		} else if( spTimeStamp.length() > 20 ){
			throw new CommonModuleException(safINVALID_TIMESTAMP_LENGTH);

		} else if( spOperator.length() > 100 ){
			throw new CommonModuleException(safINVALID_OPERATOR);
		}		
		
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd HH:mm:ss");

		Date paramDate = (Date)formatter.parse(spTimeStamp);
		Date rightNow = new Date();		
		if(paramDate.after(rightNow)){	//if time stamp is later than now
			throw new CommonModuleException(safINVALID_TIMESTAMP);
		}
		
		if (paramDate.getTime() < rightNow.getTime() - 120*60*1000 ){ //if time stamp is older than 120 minutes
			throw new CommonModuleException(safINVALID_TIMESTAMP);
		}
		
	}
	
	/**
	 * @param param
	 * @param key
	 * @return
	 */
	private String EncryptParam3DES(String param, String key) {
        Security.addProvider(new  com.sun.crypto.provider.SunJCE());
        StringBuffer temp_buf = new StringBuffer();

        param = (param == null ? "" : param);

        if(param.length()%8!=0)
            for(int i=8-(param.length()%8); i>0; i--)
                param += " ";
        try {
            DESedeKeySpec    desKeySpec = new DESedeKeySpec(key.getBytes());
            SecretKeyFactory keyFac     = SecretKeyFactory.getInstance("DESede");
            SecretKey        pbeKey     = keyFac.generateSecret(desKeySpec);
            Cipher           pbeCipher  = Cipher.getInstance("DESede/ECB/NoPadding");

            pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey);

            byte plain_password[] = param.getBytes();

            byte encrypt_password[] = pbeCipher.doFinal(plain_password);

            for(int i=0; i<encrypt_password.length; i++) {
                this.byte2hex(encrypt_password[i], temp_buf);
            }
        }
        catch(Exception e) {
        	Logger.LOG_NOHUP.debug(e.toString());
        }

        return temp_buf.toString();
    }	
	
    /**
     * @param b
     * @param buf
     */
    private void byte2hex(byte b, StringBuffer buf) {
        char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
                            '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        int high = ((b & 0xf0) >> 4);
        int low = (b & 0x0f);
        buf.append(hexChars[high]);
        buf.append(hexChars[low]);
    }	
    
   private static String bytesToHex(byte[] data)
   {
       StringBuffer buf = new StringBuffer();
       for (int i = 0; i < data.length; i++)
       {
           buf.append(byteToHex(data[i]).toUpperCase());
       }
       return (buf.toString());
   }

   
   private static String byteToHex(byte b) {
       char hexDigit[] = {
           '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
           'a', 'b', 'c', 'd', 'e', 'f'
       };
       char array[] = {
           hexDigit[b >> 4 & 0xf], hexDigit[b & 0xf]
       };
       return new String(array);
   }

   private static final String hex[] = {
           "%00", "%01", "%02", "%03", "%04", "%05", "%06", "%07", "%08", "%09",
           "%0a", "%0b", "%0c", "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13",
           "%14", "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c", "%1d",
           "%1e", "%1f", "%20", "%21", "%22", "%23", "%24", "%25", "%26", "%27",
           "%28", "%29", "%2a", "%2b", "%2c", "%2d", "%2e", "%2f", "%30", "%31",
           "%32", "%33", "%34", "%35", "%36", "%37", "%38", "%39", "%3a", "%3b",
           "%3c", "%3d", "%3e", "%3f", "%40", "%41", "%42", "%43", "%44", "%45",
           "%46", "%47", "%48", "%49", "%4a", "%4b", "%4c", "%4d", "%4e", "%4f",
           "%50", "%51", "%52", "%53", "%54", "%55", "%56", "%57", "%58", "%59",
           "%5a", "%5b", "%5c", "%5d", "%5e", "%5f", "%60", "%61", "%62", "%63",
           "%64", "%65", "%66", "%67", "%68", "%69", "%6a", "%6b", "%6c", "%6d",
           "%6e", "%6f", "%70", "%71", "%72", "%73", "%74", "%75", "%76", "%77",
           "%78", "%79", "%7a", "%7b", "%7c", "%7d", "%7e", "%7f", "%80", "%81",
           "%82", "%83", "%84", "%85", "%86", "%87", "%88", "%89", "%8a", "%8b",
           "%8c", "%8d", "%8e", "%8f", "%90", "%91", "%92", "%93", "%94", "%95",
           "%96", "%97", "%98", "%99", "%9a", "%9b", "%9c", "%9d", "%9e", "%9f",
           "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7", "%a8", "%a9",
           "%aa", "%ab", "%ac", "%ad", "%ae", "%af", "%b0", "%b1", "%b2", "%b3",
           "%b4", "%b5", "%b6", "%b7", "%b8", "%b9", "%ba", "%bb", "%bc", "%bd",
           "%be", "%bf", "%c0", "%c1", "%c2", "%c3", "%c4", "%c5", "%c6", "%c7",
           "%c8", "%c9", "%ca", "%cb", "%cc", "%cd", "%ce", "%cf", "%d0", "%d1",
           "%d2", "%d3", "%d4", "%d5", "%d6", "%d7", "%d8", "%d9", "%da", "%db",
           "%dc", "%dd", "%de", "%df", "%e0", "%e1", "%e2", "%e3", "%e4", "%e5",
           "%e6", "%e7", "%e8", "%e9", "%ea", "%eb", "%ec", "%ed", "%ee", "%ef",
           "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", "%f8", "%f9",
           "%fa", "%fb", "%fc", "%fd", "%fe", "%ff"
   };
	
}